/**********************************************
    Trabajo Práctico de Laboratorio 3
    Autores:
    2do Cuatrimestre 2012
    Prof: Daniel Barrientos
*************************************************/

#include "headers/partida.h"
#include "headers/gameConstants.h"
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

char* MSG_INGRESAR_POSICION = "Ingresar posicion para jugar: ";
char* MSG_EVALUAR_POSICION = "El oponente ingreso la siguiente posicion: ";
char* MSG_FIN_DEL_JUEGO = "FIN DEL JUEGO: el ganador es ";

void *Partida_jugarAsincronicamente(void *partida) {
	Partida *pPartida = (Partida *) partida;
	Partida_jugar(pPartida);
}

int ejecutarTurno(Jugador* jugador1, Jugador* jugador2);   // implementacion mas abajo

Partida* Partida_crear(Jugador* j1, Jugador* j2){
    Partida* partida = malloc(sizeof(Partida));
    partida->jugador1 = j1;
    partida->jugador2 = j2;
    partida->status = STATUS_INACTIVA;

    return partida;
}

void Partida_destroy(Partida *partida) {
	close(partida->socketJugador1);
	close(partida->socketJugador2);

	// libero recursos
	free(partida->jugador1);
	free(partida->jugador2);
	free(partida);
}

void Partida_iniciarAsincronicamente(Partida *partida) {
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
	int rc;
    rc = pthread_create(&(partida->thread), &attr, Partida_jugarAsincronicamente, (void *)partida);
    if (rc) {
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(EXIT_FAILURE);
    }
    pthread_attr_destroy(&attr);
}

void Partida_join(Partida *partida) {
	void *status;
	pthread_join(partida->thread, &status);
}

// Desarrolla la partida entre ambos jugadores.
void Partida_jugar(Partida* partida){
    int proxTurno = 0;
    int turnoResult;

    partida->status = STATUS_ACTIVA;
    while( partida->status == STATUS_ACTIVA ){
        if(proxTurno % 2 == 0){
        	turnoResult = ejecutarTurno(partida->jugador1, partida->jugador2);
        }else{
        	turnoResult = ejecutarTurno(partida->jugador2, partida->jugador1);
        }

        if( turnoResult == FIN_DEL_JUEGO){
            partida->status = STATUS_INACTIVA;
        }
    }
}

// Ejecuta un turno de la partida, y devuelve el resultado del turno
int ejecutarTurno(Jugador* jugador1, Jugador* jugador2){
    char userInput[10];    // formato  posx-posy. Ej: 8-4
    int n;
    int result;
    char* responseString;

    //Peddir a jugador 1 q ingrese una posicion
    write( Jugador_getSocket(jugador1), MSG_INGRESAR_POSICION, strlen(MSG_INGRESAR_POSICION)+1 );
    memset(userInput, '\0', 10);
    n = read( Jugador_getSocket(jugador1), userInput, 10);

    // TODO: Preguntar a jugador 2 si la posicion es AGUA - HUNDIDO - FIN DEL JUEGO y guardar en result
    write( Jugador_getSocket(jugador2), MSG_EVALUAR_POSICION, strlen(MSG_EVALUAR_POSICION)+1 );
    write( Jugador_getSocket(jugador2), userInput, n);
    memset(userInput, '\0', 10);
    n = read( Jugador_getSocket(jugador2), userInput, 10);

    // TODO: mandar resultado del turno a jugador1. Si el result fue FIN_DEL_JUEGO -> enviar mensaje a ambos jugadores
    if( atoi(userInput) == FIN_DEL_JUEGO ){
        responseString = malloc( (40 + sizeof(MSG_FIN_DEL_JUEGO)) * sizeof(char) );
        memset(responseString, '\0', sizeof(responseString));
        strcat(responseString, MSG_FIN_DEL_JUEGO);
        strcat(responseString, Jugador_getNombre(jugador1));

        write( Jugador_getSocket(jugador1), responseString, sizeof(responseString) );
        write( Jugador_getSocket(jugador2), responseString, sizeof(responseString) );
    }else if(atoi(userInput) == AGUA){
        responseString = "AGUA";
        write( Jugador_getSocket(jugador1), responseString, sizeof(responseString) );
    }else if(atoi(userInput) == HUNDIDO){
        responseString = "HUNDIDO";
        write( Jugador_getSocket(jugador1), responseString, sizeof(responseString) );
    }

    return result;
}


